package org.example.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.example.aiservice.StarRocksAIService;
import org.example.entity.AnalysisEvent;
import org.example.entity.QueryRequest;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.FluxSink;

import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class AnalysisService {

    private final StarRocksAIService starRocksAIService;
    private final DatabaseService databaseService;
    private final ObjectMapper objectMapper;

    public AnalysisService(StarRocksAIService starRocksAIService,
                           DatabaseService databaseService,
                           ObjectMapper objectMapper) {
        this.starRocksAIService = starRocksAIService;
        this.databaseService = databaseService;
        this.objectMapper = objectMapper;
    }

    /**
     * 核心分析流程：SQL生成 → 数据查询 → 图表生成 → 分析总结
     */
    public Flux<AnalysisEvent> analyzeQuery(QueryRequest request) {
        return Flux.create(sink -> {
            try {
                String userQuery = request.getQuery();
                log.info("开始分析查询: {}", userQuery);

                // 1. 生成SQL并执行查询
                sink.next(AnalysisEvent.status("sql_generation", "正在生成SQL..."));
                // String metadata = databaseService.getSimplifiedDatabaseMetadata();
                // String sql = starRocksAIService.generateSQL(userQuery, metadata);
                String sql = """
                        SELECT
                            p.category,
                            SUM(o.price * o.quantity) AS total_sales,
                            SUM(o.price * o.quantity) / SUM(SUM(o.price * o.quantity)) OVER () AS sales_ratio
                        FROM
                            orders o
                        JOIN
                            products p ON o.product_name = p.product_name
                        GROUP BY
                            p.category;
                        """;
                sink.next(AnalysisEvent.sql(sql));

                // 2. 执行查询获取数据
                sink.next(AnalysisEvent.status("data_analysis", "正在查询数据..."));
                List<Map<String, Object>> data = databaseService.executeQuery(sql);
                sink.next(AnalysisEvent.data(data));

                if (data.isEmpty()) {
                    sink.next(AnalysisEvent.error("data_analysis", "查询结果为空"));
                    sink.complete();
                    return;
                }

                // 3. 生成图表配置
                sink.next(AnalysisEvent.status("chart_generation", "正在生成图表..."));
                Map<String, Object> chartConfig = generateChartConfig(data, userQuery);
                sink.next(AnalysisEvent.chart(chartConfig));

                // 4. 流式生成分析总结
                sink.next(AnalysisEvent.status("analysis_streaming", "正在生成分析报告..."));
                startStreamingAnalysis(sink, data, userQuery, request.getChartType());

            } catch (Exception e) {
                log.error("分析流程异常", e);
                sink.next(AnalysisEvent.error("processing", e.getMessage()));
                sink.complete();
            }
        });
    }

    /**
     * 生成图表配置
     */
    private Map<String, Object> generateChartConfig(List<Map<String, Object>> data, String userQuery) {
        try {
            List<String> columns = data.isEmpty() ? List.of() : List.copyOf(data.get(0).keySet());
            String rawChartConfig = starRocksAIService.generateChartConfig(data, columns, userQuery);

            // 清理JSON配置
            String cleanedConfig = rawChartConfig
                    .replace("```json", "")
                    .replace("```", "")
                    .trim();

            return objectMapper.readValue(cleanedConfig, Map.class);
        } catch (Exception e) {
            log.error("图表配置生成失败", e);
            return Map.of("error", "图表生成失败: " + e.getMessage());
        }
    }

    /**
     * 启动流式分析
     */
    private void startStreamingAnalysis(FluxSink<AnalysisEvent> sink, List<Map<String, Object>> data,
                                        String userQuery, String chartType) {
        StringBuilder fullContent = new StringBuilder();

        starRocksAIService.analyzeDataStream(data, userQuery, chartType)
                .subscribe(
                        chunk -> {
                            if (chunk != null && !chunk.trim().isEmpty()) {
                                fullContent.append(chunk);
                                Map<String, Object> partialData = Map.of(
                                        "content", chunk,
                                        "isComplete", false,
                                        "fullContent", fullContent.toString()
                                );
                                sink.next(new AnalysisEvent("summary_chunk", "analysis_streaming",
                                        partialData, "分析中..."));
                            }
                        },
                        error -> {
                            log.error("流式分析失败", error);
                            sink.next(AnalysisEvent.error("analysis_streaming", error.getMessage()));
                            sink.complete();
                        },
                        () -> {
                            Map<String, Object> completeData = Map.of(
                                    "content", "",
                                    "isComplete", true,
                                    "fullContent", fullContent.toString()
                            );
                            sink.next(new AnalysisEvent("summary_complete", "analysis_complete",
                                    completeData, "分析完成"));
                            sink.complete();
                        }
                );
    }
}